package com.wondertek.poms.service.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.wondertek.poms.common.constant.Constants;
import com.wondertek.poms.common.exception.MessageCodes;
import com.wondertek.poms.common.utils.excel.ImportExcel;
import com.wondertek.poms.common.utils.validate.ValidateFilter;
import com.wondertek.poms.common.vo.PageBean;
import com.wondertek.poms.common.vo.ResultBean;
import com.wondertek.poms.core.service.IProductGropMemberService;
import com.wondertek.poms.core.service.IProductGroupService;
import com.wondertek.poms.core.service.IProductService;
import com.wondertek.poms.dao.po.ChannelPackage;
import com.wondertek.poms.dao.po.Product;
import com.wondertek.poms.dao.po.ProductGroup;
import com.wondertek.poms.dao.pojo.ProductGroupExcelPojo;
import com.wondertek.poms.dao.pojo.ProductGroupPojo;
import com.wondertek.poms.dao.pojo.ProductPojo;
import com.wondertek.poms.service.message.SendAbility;
import com.wondertek.poms.service.vo.ProductGroupVo;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

@Api(value = "ProductGroupController", description = "产品组管理")
@RestController
@RequestMapping(value = "/product-group")
@Slf4j
public class ProductGroupController {

    @Autowired
    private IProductGroupService productGroupService;
    @Autowired
    private IProductGropMemberService productGropMemberService;
    @Autowired
    private IProductService productService;
    @Autowired
    private SendAbility sendAbility;


    @GetMapping(value = "/list")
    @ResponseBody
    public ResultBean list(ProductGroupVo productGroupVo,
                           @RequestParam(defaultValue = "1") int page,
                           @RequestParam(defaultValue = "20") int rows,
                           @RequestParam(defaultValue = "CREATE_TIME") String sidx,
                           @RequestParam(defaultValue = "desc") String sord){
        ProductGroupPojo productGroupPojo=new ProductGroupPojo();
        BeanUtils.copyProperties(productGroupVo,productGroupPojo);
        Page<ProductGroupPojo> list=productGroupService.findAll(productGroupPojo,page,rows,sord,sidx);
        return PageBean.ok(list.getTotalPages(),list.getTotalElements(),list.getContent());
    }

    @PostMapping(value = "/add")
    @ResponseBody
    public ResultBean add(@RequestBody ProductGroupVo productGroupVo){
        List<String> messageList = ValidateFilter.getFilterMessage(productGroupVo, Constants.VALIDATE_DEFAULT);
        if (!messageList.isEmpty()) {
            return ResultBean.error(messageList.toString());
        }
        if(isRepeat(productGroupVo)){
            return ResultBean.error(MessageCodes.get(MessageCodes.M980014));
        }
        ProductGroupPojo productGroupPojo=new ProductGroupPojo();
        BeanUtils.copyProperties(productGroupVo,productGroupPojo);
        ProductGroup productGroup=productGroupService.saveProductGroup(productGroupPojo);
        return ResultBean.ok(productGroup);
    }

    @DeleteMapping(value = "/delete")
    @ResponseBody
    public ResultBean delete(String ids){
        if (StrUtil.isBlank(ids)) {
            return ResultBean.error(MessageCodes.get(MessageCodes.M980203));
        }
        StringBuffer msg = new StringBuffer();
        StringBuffer errMessage = new StringBuffer();
        AtomicInteger errorNum = new AtomicInteger();//错误数
        AtomicInteger successNum = new AtomicInteger();//成功数
        String[] idArray = ids.split(",|，");
        for(String id:idArray){
            if(checkDelData(id,errMessage,errorNum)){
                productGroupService.deleteGroup(id);
                successNum.addAndGet(1);
            }
        }
        msg.append("删除成功"+successNum.get()+"条. ");
        if (errorNum.get() > 0) {
            msg.append("删除失败"+errorNum.get()+"条，失败原因：").append(errMessage);
            return ResultBean.error(msg.toString());
        }
        return ResultBean.ok();
    }

    public Boolean checkDelData(String id, StringBuffer errMessage, AtomicInteger errorNum) {
        Boolean flag = true;
        ProductGroup productGroup=productGroupService.findById(Convert.toLong(id));
        if("0".equals(productGroup.getStatus())){
            errorNum.addAndGet(1);
            flag = false;
            errMessage.append("产品组:"+id+"已发布.  ");
        }
        return flag;
    }

    @GetMapping(value = "/get")
    @ResponseBody
    public ResultBean get(Long id){
        if (id == null) {
            return ResultBean.error(MessageCodes.get(MessageCodes.M980021));
        }
        ProductGroupPojo productGroupPojo=productGroupService.getById(id);
        return ResultBean.ok(productGroupPojo);
    }

    @GetMapping(value = "/get-products")
    @ResponseBody
    public ResultBean getProducts(Long id){
        if (id == null) {
            return ResultBean.error(MessageCodes.get(MessageCodes.M980021));
        }
        ProductGroupPojo productGroupPojo=productGroupService.getById(id);
        List<ProductPojo> list=new ArrayList<>();
        if(!"".equals(productGroupPojo.getProductIds())){
            list=productService.getByProductIds(productGroupPojo.getProductIds());
        }
        return ResultBean.ok(list);
    }

    @PutMapping(value = "/edit")
    @ResponseBody
    public ResultBean edit(@RequestBody ProductGroupVo productGroupVo){
        ProductGroup productGroup=productGroupService.findById(productGroupVo.getGroupId());
        if(productGroup!=null){
            if(!productGroupVo.getGroupName().equals(productGroup.getGroupName())){
                if(isRepeat(productGroupVo)){
                    return ResultBean.error(MessageCodes.get(MessageCodes.M980014));
                }
            }

            BeanUtils.copyProperties(productGroupVo,productGroup);
            productGroup.setStatus("2");
            ProductGroup.putTimeAndUser(productGroup);
            productGroupService.save(productGroup);
        }
        return ResultBean.ok();
    }

    @GetMapping(value = "/add-products")
    @ResponseBody
    public ResultBean addProducts(String groupId, String productIds){
        if(StrUtil.isBlank(productIds)){
            return ResultBean.error(MessageCodes.get(MessageCodes.M980203));
        }
        productGropMemberService.saveProductIds(groupId,productIds);
        return ResultBean.ok();
    }

    @DeleteMapping(value = "/del-products")
    @ResponseBody
    public ResultBean delProducts(String groupId, String productIds){
        if(StrUtil.isBlank(productIds)){
            return ResultBean.error(MessageCodes.get(MessageCodes.M980203));
        }
        productGropMemberService.delProductIds(groupId,productIds);
        return ResultBean.ok();
    }

    @GetMapping(value = "/get-all-product-groupId")
    @ResponseBody
    public ResultBean getAllProductGroupId(String vo){
        List<Long> list=productGroupService.getAllProductGroupId(vo);
        return ResultBean.ok(list);
    }

    @GetMapping(value = "/get-all-product-group-name")
    @ResponseBody
    public ResultBean getAllProductGroupName(String vo){
        List<String> list=productGroupService.getAllProductGroupName(vo);
        return ResultBean.ok(list);
    }

    @GetMapping(value = "/get-all-productId")
    @ResponseBody
    public ResultBean getAllProductId(String vo){
        List<Long> list=productService.getAllProductId(vo);
        return ResultBean.ok(list);
    }

    @PostMapping(value = "/import")
    public ResultBean importProductGroup(MultipartFile file) throws Exception{
        StringBuffer msg = new StringBuffer("导入数据总数->");
        StringBuffer errMessage = new StringBuffer(".错误原因是->");
        AtomicInteger errNum = new AtomicInteger();// 全局错误数
        List<ProductGroupExcelPojo> list=new ArrayList<>();
        try{
            ImportExcel ei = new ImportExcel(file, 1, 0);
            List<ProductGroupExcelPojo> dataList=ei.getDataList(ProductGroupExcelPojo.class);
            if (CollectionUtil.isNotEmpty(dataList)) {
                msg.append(dataList.size() + ".错误数据数->");
                dataList.forEach(v -> importData(errMessage, errNum, v, list));
            } else {
                return ResultBean.error(MessageCodes.get(MessageCodes.M980205));
            }

            if (CollectionUtil.isNotEmpty(list)){
                for(ProductGroupExcelPojo excelPojo:list){
                    ProductGroupPojo productGroupPojo=new ProductGroupPojo();
                    BeanUtils.copyProperties(excelPojo,productGroupPojo);
                    productGroupService.saveProductGroup(productGroupPojo);
                }
            }
            msg.append(errNum);
            msg.append(errMessage);
        }catch (Exception e){
            e.printStackTrace();
            return ResultBean.error(MessageCodes.get(MessageCodes.M980000));
        }
        if (errNum.get() > 0) {
            return ResultBean.error(msg.toString().replace("[", "").replace("]", "").replace("[]", "").replace("!", ""));
        }
        return ResultBean.ok();
    }


    //TODO  产品组发布
    @GetMapping(value = "/online")
    @ResponseBody
    public ResultBean online(String ids){
        if(StrUtil.isBlank(ids)){
            return ResultBean.error(MessageCodes.get(MessageCodes.M980203));
        }
        StringBuffer msg = new StringBuffer();
        StringBuffer errMessage = new StringBuffer();
        AtomicInteger errorNum = new AtomicInteger();//错误数
        AtomicInteger successNum = new AtomicInteger();//成功数
        String[] idArray = ids.split(",|，");
        for(String id:idArray){
            ProductGroup productGroup=productGroupService.get(Convert.toLong(id));
            publishGroup(productGroup,1,errMessage,errorNum,successNum);
        }
        msg.append("发布成功"+successNum.get()+"条. ");
        if (errorNum.get() > 0) {
            msg.append("发布失败"+errorNum.get()+"条：").append(errMessage);
            return ResultBean.error(msg.toString());
        }
        return ResultBean.ok(msg);
    }

    //todo 产品组撤回
    @GetMapping(value = "/offline")
    @ResponseBody
    public ResultBean offline(String ids){
        if(StrUtil.isBlank(ids)){
            return ResultBean.error(MessageCodes.get(MessageCodes.M980203));
        }
        StringBuffer msg = new StringBuffer();
        StringBuffer errMessage = new StringBuffer();
        AtomicInteger errorNum = new AtomicInteger();//错误数
        AtomicInteger successNum = new AtomicInteger();//成功数
        String[] idArray = ids.split(",|，");
        for(String id:idArray){
            ProductGroup productGroup=productGroupService.get(Convert.toLong(id));
            publishGroup(productGroup,2,errMessage,errorNum,successNum);
        }
        msg.append("发布成功"+successNum.get()+"条. ");
        if (errorNum.get() > 0) {
            msg.append("发布失败"+errorNum.get()+"条：").append(errMessage);
            return ResultBean.error(msg.toString());
        }
        return ResultBean.ok(msg);
    }

    public void publishGroup(ProductGroup productGroup,int oprCode,StringBuffer errMessage,AtomicInteger errorNum,AtomicInteger successNum){
        String type="2";
        log.info("开始发送能力平台流程|产品组id:"+productGroup.getGroupId());
        Boolean flag = sendAbility.sendToAbility(productGroup.getGroupId(),oprCode,productGroup.getGroupName(),type);
        log.info("发送能力平台流程结束|产品组id:"+productGroup.getGroupId()+",结果："+flag);
        if(flag){
            successNum.addAndGet(1);
            if(oprCode==1){
                productGroup.setStatus("0");
            }else {
                productGroup.setStatus("1");
            }
            ProductGroup.putTimeAndUser(productGroup);
            productGroupService.save(productGroup);
        }else {
            errorNum.addAndGet(1);
            errMessage.append("产品组：").append(productGroup.getGroupId()).append("失败！");
        }
    }

    public void importData(StringBuffer errMessage, AtomicInteger errNum, ProductGroupExcelPojo productGroupExcelPojo, List<ProductGroupExcelPojo> list){
        if(productGroupExcelPojo !=null){
            Boolean flag=true;
            List<String> messageList = ValidateFilter.getFilterMessage(productGroupExcelPojo, Constants.VALIDATE_DEFAULT);
            flag = checkData(errMessage, errNum, productGroupExcelPojo, flag, messageList);
            if (flag ) {
                list.add(productGroupExcelPojo);
            }
        }
    }

    public Boolean checkData(StringBuffer errMessage, AtomicInteger errNum, ProductGroupExcelPojo productGroupExcelPojo, Boolean flag, List<String> messageList){
        if (flag && !messageList.isEmpty()) {
            errNum.addAndGet(1);
            flag = false;
            errMessage.append("导入出错：" + messageList.toString() + ".  ");
        }

        if(flag){
            ProductGroupVo productGroupVo=new ProductGroupVo();
            productGroupVo.setGroupName(productGroupExcelPojo.getGroupName());
            if(isRepeat(productGroupVo)){
                errNum.addAndGet(1);
                flag = false;
                errMessage.append("导入出错：产品组名：" + productGroupExcelPojo.getGroupName() + " " + MessageCodes.get(MessageCodes.M980014) + ".  ");
            }
        }

        if(flag && !"".equals(productGroupExcelPojo.getProductIds())){
            String[] productIds = productGroupExcelPojo.getProductIds().split(",|，");
            for (String productId : productIds) {
                Product product=productService.getByProductId(productId.toString());
                if(product==null){
                    errNum.addAndGet(1);
                    flag = false;
                    errMessage.append("导入出错：产品组名：" + productGroupExcelPojo.getGroupName() + "的计费点："+productId+" 不存在.  ");
                }
            }
        }
        return flag;
    }



    public boolean isRepeat(ProductGroupVo productGroupVo){
        ProductGroup temp=new ProductGroup();
        temp.setGroupName(productGroupVo.getGroupName());
        Optional<ProductGroup> productGroupOpt=productGroupService.findOne(Example.of(temp));
        if(productGroupOpt.isPresent()){
            ProductGroup productGroup=productGroupOpt.get();
            if (productGroupVo.getGroupId() != null && productGroupVo.getGroupId() != productGroup.getGroupId())
                return true;
            else if (productGroupVo.getGroupId() == null)
                return true;
        }
        return false;
    }
}
